home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / Papers / C++ Exceptions / µShell / Array Classes / OTList.h < prev   
Encoding:
C/C++ Source or Header  |  1998-06-15  |  8.1 KB  |  184 lines  |  [TEXT/CWIE]

  1. #ifndef __OTLIST__
  2. #define __OTLIST__
  3. #pragma once
  4.  
  5. #include <OpenTransport.h>
  6.  
  7. //
  8. //    Helper functions for the templates below
  9. //
  10. void* OTLinkNextObject(void* obj, int linkOffset);
  11. void* OTLinkIndexObject(void* obj, int count, int linkOffset);
  12.  
  13.  
  14. template <class ObjClass, int linkOffset>
  15. class OTLinkPtr
  16. {
  17. protected:
  18.     ObjClass*    fObject;
  19.  
  20. public:
  21.     //
  22.     //    static inlines for adding fudge factors, casting, etc.
  23.     //
  24.     static inline int                GetLinkOffset()                        { return linkOffset;                                        }
  25.  
  26.     static inline OTLink&            ObjectToLink(ObjClass& obj)            { return *(OTLink*)     (((char*) &obj)  + linkOffset);        }
  27.     static inline ObjClass&            LinkToObject(OTLink& link)            { return *(ObjClass*)    (((char*) &link) - linkOffset);        }
  28.     static inline OTLink*            ObjectToLink(ObjClass* obj)            { return obj  ? &ObjectToLink(*obj)  : nil;                    }
  29.     static inline ObjClass*            LinkToObject(OTLink* link)            { return link ? &LinkToObject(*link) : nil;                    }
  30.  
  31.     static inline const OTLink&        ObjectToLink(const ObjClass& obj)    { return *(const OTLink*)    (((char*) &obj)  + linkOffset);    }
  32.     static inline const ObjClass&    LinkToObject(const OTLink& link)    { return *(const ObjClass*)    (((char*) &link) - linkOffset);    }
  33.     static inline const OTLink*        ObjectToLink(const ObjClass* obj)    { return obj  ? &ObjectToLink(*obj)  : nil;                    }
  34.     static inline const ObjClass*    LinkToObject(const OTLink* link)    { return link ? &LinkToObject(*link) : nil;                    }
  35.  
  36.  
  37.     //
  38.     //    Constructors
  39.     //
  40.     inline OTLinkPtr()                                 : fObject(nil)                    {}
  41.     inline OTLinkPtr(const OTLinkPtr& rhs)            : fObject(rhs.fObject)            {}
  42.     inline OTLinkPtr(const ObjClass* rhs)    const    : fObject(rhs.fObject)            {}
  43.     inline OTLinkPtr(const OTLink* rhs)        const    : fObject(LinkToObject(rhs))    {}
  44.     inline OTLinkPtr(ObjClass* rhs)                    : fObject(rhs)                    {}
  45.     inline OTLinkPtr(OTLink* rhs)                    : fObject(LinkToObject(rhs))    {}
  46.     
  47.     //
  48.     //    Desctuctor -- CodeWarrior refuses to inline explicit empty desturctor
  49.     //
  50. //    inline ~OTLinkPtr()                                                {}
  51.     
  52.     //
  53.     //    Access methods
  54.     //
  55.     inline OTLink*            GetLinkPtr()            { return ObjectToLink(fObject);        }
  56.     inline const OTLink*    GetLinkPtr()    const    { return ObjectToLink(fObject);        }
  57.     inline OTLink&            GetLinkRef()            { return ObjectToLink(*fObject);    }
  58.     inline const OTLink&    GetLinkRef()    const    { return ObjectToLink(*fObject);    }
  59.     inline ObjClass*        GetObjectPtr()            { return fObject; }
  60.     inline const ObjClass*    GetObjectPtr()    const    { return fObject; }
  61.     
  62.     inline ObjClass*        NextObject()            { return (ObjClass*) OTLinkNextObject(fObject, linkOffset); }
  63.     inline OTLink*            NextLink()                { return OTLinkNext(GetLinkPtr()); }
  64.  
  65. #if 0    // various attempt to trick codewarrior into generating decent code
  66.     inline OTLinkPtr        Next()                    { return OTLinkPtr(ObjectToLink(*fObject).fNext); }
  67.     inline OTLinkPtr        Next()                    { return OTLinkPtr(fObject ? ObjectToLink(*fObject).fNext : nil); }
  68.     inline OTLinkPtr        Next()                    { return OTLinkPtr((ObjClass*) OTLinkIndexObj((char*) fObject, linkOffset, 1)); }
  69.     inline OTLinkPtr        Next()                    { return OTLinkPtr((ObjClass*) OTLinkIndex<linkOffset>(fObject, 1)); }
  70. #else
  71.     inline OTLinkPtr        Next()                    { return OTLinkPtr(NextObject()); }
  72. #endif
  73.  
  74.     //
  75.     //    Standard operators
  76.     //
  77.     inline OTLinkPtr&        operator=(const OTLinkPtr& rhs)            { fObject = rhs.fObject;        return *this; }
  78.     inline OTLinkPtr&        operator=(const ObjClass* rhs)            { fObject = rhs;                return *this; }
  79.     inline OTLinkPtr&        operator=(const OTLink* rhs)            { fObject = LinkToObject(rhs);    return *this; }
  80.  
  81.     inline OTLinkPtr&        operator&()                                { return *this;                        }
  82.     inline const OTLinkPtr&    operator&() const                        { return *this;                        }
  83.  
  84.     inline const ObjClass&    operator*()        const                    { return *fObject;                    }
  85.     inline ObjClass&        operator*()                                { return *fObject;                    }
  86.  
  87.     inline ObjClass*        operator->()                            { return fObject;                    }
  88.     inline const ObjClass*    operator->() const                        { return fObject;                    }
  89.  
  90.     inline ObjClass&        operator[](int index)                    { return *(ObjClass*) OTLinkIndexObject(fObject, index, linkOffset); }
  91.     inline const ObjClass&    operator[](int index) const                { return *(ObjClass*) OTLinkIndexObject(fObject, index, linkOffset); }
  92.  
  93.     //
  94.     //    Type coercion operators
  95.     //
  96.     inline operator OTLink*()                                        { return ObjectToLink(fObject);        }
  97.     inline operator const OTLink*() const                            { return ObjectToLink(fObject);        }
  98.  
  99.     inline operator ObjClass*()                                        { return fObject;                    }
  100.     inline operator const ObjClass*() const                            { return fObject;                    }
  101.  
  102.     inline operator void*()                                         { return fObject;                    }
  103.     inline operator const void*() const                                { return fObject;                    }
  104.  
  105.     inline operator bool() const                                    { return fObject != nil;            }
  106.  
  107. };
  108.  
  109. template <class ObjClass, int linkOffset>
  110. class OTLIFOOf : public OTLIFO
  111. {
  112. public:
  113.     typedef OTLinkPtr<ObjClass, linkOffset>    LinkPtr;    
  114.  
  115.     inline OTLIFOOf()    { Init(); }
  116.  
  117.     inline void        Enqueue(LinkPtr link)                            { OTLIFO::Enqueue(link);                    }
  118.     inline void        Enqueue(ObjClass* object)                        { Enqueue( LinkPtr::ObjectToLink(object));    }
  119.     inline void        Enqueue(ObjClass& object)                        { Enqueue(&LinkPtr::ObjectToLink(object));    }
  120.     
  121.     inline LinkPtr    Dequeue()                                        { return LinkPtr(OTLIFO::Dequeue());        }
  122.     inline LinkPtr    StealList()                                        { return LinkPtr(OTLIFO::StealList());        }
  123. };
  124.  
  125. template <class ObjClass, int linkOffset>
  126. class OTListOf : public OTList
  127. {
  128. public:
  129.     typedef OTLinkPtr<ObjClass, linkOffset>    LinkPtr;    
  130.     typedef Boolean (*SearchProcPtr)(const void* ref, LinkPtr linkToCheck);
  131.     typedef ObjClass* ObjPtr;
  132.  
  133.     inline OTListOf()    { Init(); }
  134.  
  135.     inline void        AddFirst(LinkPtr link)                            { OTList::AddFirst( link );                            }
  136.     inline void        AddLast(LinkPtr link)                            { OTList::AddLast( link );                            }
  137.     inline void        AddFirst(ObjClass& object)                        { OTList::AddFirst(&LinkPtr::ObjectToLink(object));    }
  138.     inline void        AddLast(ObjClass& object)                        { OTList::AddLast(&LinkPtr::ObjectToLink(object));    }
  139.  
  140.     inline bool        Remove(LinkPtr link)                            { return OTList::RemoveLink(link);                             }
  141.     inline bool        Remove(ObjClass* obj)                            { return OTList::RemoveLink(LinkPtr::ObjectToLink(obj));    }
  142.     inline bool        Remove(ObjClass& obj)                            { return OTList::RemoveLink(&LinkPtr::ObjectToLink(obj));    }
  143.  
  144.     inline LinkPtr    GetFirst()                                        { return LinkPtr(OTList::GetFirst());                }
  145.     inline LinkPtr    GetLast()                                        { return LinkPtr(OTList::GetLast());                }
  146.     inline LinkPtr    RemoveFirst()                                    { return LinkPtr(OTList::RemoveFirst());            }
  147.     inline LinkPtr    RemoveLast()                                    { return LinkPtr(OTList::RemoveLast());                }
  148.  
  149.     inline bool        IsInList(LinkPtr link)                            { return OTList::IsInList(link);                             }
  150.     inline bool        IsInList(ObjClass* obj)                            { return OTList::IsInList(LinkPtr::ObjectToLink(obj));         }
  151.     inline bool        IsInList(ObjClass& obj)                            { return OTList::IsInList(&LinkPtr::ObjectToLink(obj));         }
  152.  
  153.     inline LinkPtr    FindLink(SearchProcPtr proc, const void* ref)    { return OTList::FindLink((OTListSearchProcPtr) proc, ref);    }
  154.     inline LinkPtr    Remove(SearchProcPtr proc, const void* ref)        { return OTList::RemoveLink(proc, ref);                        }
  155.  
  156.     inline LinkPtr    GetIndexedLink(size_t index)                    { return OTList::GetIndexedLink(index);                        }
  157. };
  158.  
  159. // Macros for declaring list/link types
  160.  
  161. #define EmbeddedLinkPtr(Class, Field)    OTLinkPtr<Class, offsetof(Class, Field)>
  162. #define EmbeddedLIFO(Class, Field)        OTLIFOOf <Class, offsetof(Class, Field)>
  163. #define EmbeddedList(Class, Field)        OTListOf <Class, offsetof(Class, Field)>
  164.  
  165.  
  166. #define DeclareEmbeddedLink(Class, Name, offset/*of(Class,f##Name) */)                        \
  167.     typedef OTLinkPtr<Class, offset>    Name##Ptr;                                            \
  168.     typedef OTLIFOOf <Class, offset>    Name##LIFO;                                            \
  169.     typedef OTListOf <Class, offset>    Name##List;                                            \
  170.     inline void Set##Name(Name##Ptr obj)    { f##Name.fNext = obj ? &obj->f##Name : nil; }    \
  171.     inline void Set##Name(Class* obj)         { f##Name.fNext = obj ? &obj->f##Name : nil; }    \
  172.     inline Name##Ptr Get##Name()             { return *(Name##Ptr*) &(f##Name);                }
  173.  
  174. /*
  175. #define DeclareEmbeddedLink(Class, Name, offset)                                            \
  176.     typedef EmbeddedLinkPtr(Class, f##Name)    Name##Ptr;                                        \
  177.     typedef EmbeddedLIFO(    Class, f##Name)    Name##LIFO;                                        \
  178.     typedef EmbeddedList(    Class, f##Name)    Name##List;                                        \
  179.     inline void Set##Name(Name##Ptr obj)    { f##Name.fNext = obj ? &obj->f##Name : nil; }    \
  180.     inline void Set##Name(Class* obj)         { f##Name.fNext = obj ? &obj->f##Name : nil; }    \
  181.     inline Name##Ptr Get##Name()             { return *(Name##Ptr*) &(f##Name);                }
  182. */
  183.  
  184. #endif __OTLIST__